/*This file is prepared for Doxygen automatic documentation generation.*/
//! \file *********************************************************************
//!
//! \brief This file manages the keyboard task.
//!
//! - Compiler:           IAR EWAVR and GNU GCC for AVR
//! - Supported devices:  AT90USB162, AT90USB82
//!
//! \author               Atmel Corporation: http://www.atmel.com \n
//!                       Support and FAQ: http://support.atmel.no/
//!
//! ***************************************************************************

/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * 3. The name of Atmel may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 *
 * 4. This software may only be redistributed and used in connection with an Atmel
 * AVR product.
 *
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
 * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

//_____  I N C L U D E S ___________________________________________________


#include "config.h"
#include <util/delay.h>
#include <stdio.h>
#include "conf_usb.h"
#include "keyboard_task.h"
#include "usb_drv.h"
#include "usb_descriptors.h"
#include "usb_standard_request.h"
#include "power_drv.h"
#include "compiler.h"


//_____ D E F I N I T I O N S ______________________________________________

// ASCII to USB HID keymap

const U8 a2usbk[] PROGMEM = {
	HID_MODIFIER_LEFT_CTRL,HID_2, 		// Null 0
	HID_MODIFIER_LEFT_CTRL,HID_A, 		// SOH 1
	HID_MODIFIER_LEFT_CTRL,HID_B, 		// STX 2 
	HID_MODIFIER_LEFT_CTRL,HID_C, 		// ETX 3 
	HID_MODIFIER_LEFT_CTRL,HID_D, 		// EOT 4 
	HID_MODIFIER_LEFT_CTRL,HID_E, 		// ENQ 5
	HID_MODIFIER_LEFT_CTRL,HID_F, 		// ACK 6
	HID_MODIFIER_LEFT_CTRL,HID_G, 		// BEL 7
	HID_MODIFIER_NONE,HID_BACKSPACE,	// BS 8
	HID_MODIFIER_NONE,HID_TAB, 		// HT 9
	HID_MODIFIER_NONE,HID_ENTER, 	// LF 10
	HID_MODIFIER_LEFT_CTRL,HID_K, 		// VT 11
	HID_MODIFIER_LEFT_CTRL,HID_L, 		// FF 12
	HID_MODIFIER_NONE,HID_HOME, 		// CR 13
	HID_MODIFIER_LEFT_CTRL,HID_N, 		// SO 14
	HID_MODIFIER_LEFT_CTRL,HID_O, 		// SI 15 
	HID_MODIFIER_LEFT_CTRL,HID_P, 		// DLE 16
	HID_MODIFIER_LEFT_CTRL,HID_Q, 		// DC1 17
	HID_MODIFIER_LEFT_CTRL,HID_R, 		// DC2 18
	HID_MODIFIER_LEFT_CTRL,HID_S, 		// DC3 19
	HID_MODIFIER_LEFT_CTRL,HID_T, 		// DC4 20
	HID_MODIFIER_LEFT_CTRL,HID_U, 		// NAK 21
	HID_MODIFIER_LEFT_CTRL,HID_V, 		// SYN 22
	HID_MODIFIER_LEFT_CTRL,HID_W, 		// ETB 23
	HID_MODIFIER_LEFT_CTRL,HID_X, 		// CAN 24 
	HID_MODIFIER_LEFT_CTRL,HID_Y, 		// EM 25
	HID_MODIFIER_LEFT_CTRL,HID_Z, 		// SUB 26
	HID_MODIFIER_NONE,HID_ESCAPE, 		// ESC 27
	HID_MODIFIER_NONE,HID_SPACEBAR,		// FS 28
	HID_MODIFIER_NONE,HID_SPACEBAR,		// GS 29
	HID_MODIFIER_NONE,HID_SPACEBAR,		// RS 30
	HID_MODIFIER_NONE,HID_SPACEBAR,		// US 31
	HID_MODIFIER_NONE,HID_SPACEBAR,		// Space 32
	HID_MODIFIER_LEFT_SHIFT,HID_1,		// ! 33
	HID_MODIFIER_LEFT_SHIFT,HID_QUOTE,// " 34
	HID_MODIFIER_LEFT_SHIFT,HID_3,  	// #	35
	HID_MODIFIER_LEFT_SHIFT,HID_4,		// $	36
	HID_MODIFIER_LEFT_SHIFT,HID_5,		// %	37
	HID_MODIFIER_LEFT_SHIFT,HID_7,		// &	38
	HID_MODIFIER_NONE,HID_QUOTE,		// '	39
	HID_MODIFIER_LEFT_SHIFT,HID_9,		// (	40
	HID_MODIFIER_LEFT_SHIFT,HID_0,		// )	41
	HID_MODIFIER_LEFT_SHIFT,HID_8,		// *	42
	HID_MODIFIER_LEFT_SHIFT,HID_PLUS,	// +	43
	HID_MODIFIER_NONE,HID_COMMA,		// ,	44	
	HID_MODIFIER_NONE,HID_UNDERSCORE,	// -	45
	HID_MODIFIER_NONE,HID_DOT,		// .	46
	HID_MODIFIER_NONE,HID_SLASH,		// /	47
	HID_MODIFIER_NONE,HID_0,		// 0	48
	HID_MODIFIER_NONE,HID_1,		// 1	49
	HID_MODIFIER_NONE,HID_2,		// 2	50
	HID_MODIFIER_NONE,HID_3,		// 3	51
	HID_MODIFIER_NONE,HID_4,		// 4	52
	HID_MODIFIER_NONE,HID_5,		// 5	53
	HID_MODIFIER_NONE,HID_6,		// 6	54
	HID_MODIFIER_NONE,HID_7,		// 7	55
	HID_MODIFIER_NONE,HID_8,		// 8	56
	HID_MODIFIER_NONE,HID_9,		// 9	57
	HID_MODIFIER_LEFT_SHIFT,HID_SCOLON,	// :	58
	HID_MODIFIER_NONE,HID_SCOLON,		// ;	59
	HID_MODIFIER_LEFT_SHIFT,HID_COMMA,	// <	60
	HID_MODIFIER_NONE,HID_PLUS,		// =	61
	HID_MODIFIER_LEFT_SHIFT,HID_DOT,	// >	62
	HID_MODIFIER_LEFT_SHIFT,HID_SLASH,	// ?	63
	HID_MODIFIER_LEFT_SHIFT,HID_2,		// @	64	
	HID_MODIFIER_LEFT_SHIFT,HID_A,		// A	65
	HID_MODIFIER_LEFT_SHIFT,HID_B,		// B	66
	HID_MODIFIER_LEFT_SHIFT,HID_C,		// C	67
	HID_MODIFIER_LEFT_SHIFT,HID_D,		// D	68
	HID_MODIFIER_LEFT_SHIFT,HID_E,		// E	69
	HID_MODIFIER_LEFT_SHIFT,HID_F,		// F	70
	HID_MODIFIER_LEFT_SHIFT,HID_G,		// G	71
	HID_MODIFIER_LEFT_SHIFT,HID_H,		// H	72
	HID_MODIFIER_LEFT_SHIFT,HID_I,		// I	73
	HID_MODIFIER_LEFT_SHIFT,HID_J,		// J	74
	HID_MODIFIER_LEFT_SHIFT,HID_K,		// K	75
	HID_MODIFIER_LEFT_SHIFT,HID_L,		// L	76
	HID_MODIFIER_LEFT_SHIFT,HID_M,		// M	77	
	HID_MODIFIER_LEFT_SHIFT,HID_N,		// N	78
	HID_MODIFIER_LEFT_SHIFT,HID_O,		// O	79
	HID_MODIFIER_LEFT_SHIFT,HID_P,		// P	80
	HID_MODIFIER_LEFT_SHIFT,HID_Q,		// Q	81	
	HID_MODIFIER_LEFT_SHIFT,HID_R,		// R	82
	HID_MODIFIER_LEFT_SHIFT,HID_S,		// S	83
	HID_MODIFIER_LEFT_SHIFT,HID_T,		// T	84
	HID_MODIFIER_LEFT_SHIFT,HID_U,		// U	85	
	HID_MODIFIER_LEFT_SHIFT,HID_V,		// V	86
	HID_MODIFIER_LEFT_SHIFT,HID_W,		// K	87
	HID_MODIFIER_LEFT_SHIFT,HID_X,		// X	88
	HID_MODIFIER_LEFT_SHIFT,HID_Y,		// Y	89
	HID_MODIFIER_LEFT_SHIFT,HID_Z,		// Z	90
	HID_MODIFIER_NONE,HID_OBRACK,		// [	91
	HID_MODIFIER_NONE,HID_BACKSLASH,	// backslash	92
	HID_MODIFIER_NONE,HID_CBRACK,		// ]	93
	HID_MODIFIER_LEFT_SHIFT,HID_6,		// ^	94
	HID_MODIFIER_LEFT_SHIFT,HID_UNDERSCORE,	// _	95
	HID_MODIFIER_NONE,HID_TILDE,		// `	96	
	HID_MODIFIER_NONE,HID_A,		// a	97
	HID_MODIFIER_NONE,HID_B,		// b	98
	HID_MODIFIER_NONE,HID_C,		// c	99	
	HID_MODIFIER_NONE,HID_D,		// d	100
	HID_MODIFIER_NONE,HID_E,		// e	101
	HID_MODIFIER_NONE,HID_F,		// f	102
	HID_MODIFIER_NONE,HID_G,		// g	103
	HID_MODIFIER_NONE,HID_H,		// h	104
	HID_MODIFIER_NONE,HID_I,		// i	105
	HID_MODIFIER_NONE,HID_J,		// j	106
	HID_MODIFIER_NONE,HID_K,		// k	107
	HID_MODIFIER_NONE,HID_L,		// l	108
	HID_MODIFIER_NONE,HID_M,		// m	109
	HID_MODIFIER_NONE,HID_N,		// n	110
	HID_MODIFIER_NONE,HID_O,		// o	111
	HID_MODIFIER_NONE,HID_P,		// p	112
	HID_MODIFIER_NONE,HID_Q,		// q	113
	HID_MODIFIER_NONE,HID_R,		// r	114
	HID_MODIFIER_NONE,HID_S,		// s	115
	HID_MODIFIER_NONE,HID_T,		// t	116
	HID_MODIFIER_NONE,HID_U,		// u	117
	HID_MODIFIER_NONE,HID_V,		// v	118
	HID_MODIFIER_NONE,HID_W,		// w	119
	HID_MODIFIER_NONE,HID_X,		// x	120
	HID_MODIFIER_NONE,HID_Y,		// y	121
	HID_MODIFIER_NONE,HID_Z,		// z	122
	HID_MODIFIER_LEFT_SHIFT,HID_OBRACK,	// {	123
	HID_MODIFIER_LEFT_SHIFT,HID_BACKSLASH,	// |	124
	HID_MODIFIER_LEFT_SHIFT,HID_CBRACK,	// }	125
	HID_MODIFIER_LEFT_SHIFT,HID_TILDE,	// ~	126
	HID_MODIFIER_LEFT_SHIFT,HID_SPACEBAR,	// _	127
};

//_____ D E C L A R A T I O N S ____________________________________________


//! @brief Entry point of the mouse management
//! This function links the mouse and the USB bus.
//!
int /*usb_*/putch(char c)//, struct __file *f)
{
	U8 t;

	if (Is_device_enumerated()) {
		Usb_select_endpoint(EP_KBD_IN);	// Tells PC where the following data is going (input from keyboard)
		if (Is_usb_write_enabled()) {
			while (Is_usb_one_bank_busy()==1);
			memcpy_P(&t, &a2usbk[c*2], sizeof(U8));	// Translate ASCII character to USB HID and send
			Usb_write_byte(t);	// Byte0: Modifier
			Usb_write_byte(0);	// Byte1: Reserved
			memcpy_P(&t, &a2usbk[c*2+1], sizeof(U8));	// Copy lookup table element to working memory
			Usb_write_byte(t);	// Byte2: Keycode 1
			Usb_write_byte(0);	// Byte2: Keycode 2
			Usb_write_byte(0);	// Byte2: Keycode 3
			Usb_write_byte(0);	// Byte2: Keycode 4
			Usb_write_byte(0);	// Byte2: Keycode 5
			Usb_write_byte(0);	// Byte2: Keycode 6
			Usb_send_in();		// Send 8-byte word via USB as keyboard code
			Usb_select_endpoint(EP_KBD_IN);	// Tell host data is from keyboard input
			while (Is_usb_one_bank_busy()==1);	// Wait for buffer to empty
			Usb_write_byte(0);		// Write key release data
			Usb_write_byte(0);
			Usb_write_byte(0);
			Usb_write_byte(0);
			Usb_write_byte(0);
			Usb_write_byte(0);
			Usb_write_byte(0);
			Usb_write_byte(0);
			Usb_send_in();			// Send key release
			while (Is_usb_one_bank_busy()==1);	// Wait for buffer to empty
		}
		
	}
	return c; 
}
